package com.itwenke.springbootdemo.shirosimple.demo;

import com.itwenke.springbootdemo.shirosimple.common.MultiThreadingTransactionManager;
import com.itwenke.springbootdemo.shirosimple.entity.BankAccount;
import com.itwenke.springbootdemo.shirosimple.service.IBankAccountService;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class MultiThreadDemo {

    @Resource
    private IBankAccountService bankAccountService;

    @Resource
    private PlatformTransactionManager platformTransactionManager;

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Transactional(rollbackFor = Exception.class)
    public void addBankAccount1() {
        new Thread(() -> {
            BankAccount bankAccount = new BankAccount();
            bankAccount.setAccount("11111111");
            bankAccount.setBalance(10000L);
            bankAccountService.addBankAccount(bankAccount);
        }).start();

        new Thread(() ->{
            BankAccount bankAccount = new BankAccount();
            bankAccount.setAccount("22222222");
            bankAccount.setBalance(10000L);
            bankAccountService.addBankAccount(bankAccount);
            throw new RuntimeException("测试事务回滚");
        }).start();
    }

    @Transactional(rollbackFor = Exception.class)
    public void addBankAccount2() {
        new Thread(() -> {
            BankAccount bankAccount = new BankAccount();
            bankAccount.setAccount("11111111");
            bankAccount.setBalance(10000L);
            bankAccountService.addBankAccount(bankAccount);
        }).start();

        new Thread(() ->{
            BankAccount bankAccount = new BankAccount();
            bankAccount.setAccount("22222222");
            bankAccount.setBalance(10000L);
            bankAccountService.addBankAccount(bankAccount);
        }).start();

        throw new RuntimeException("测试事务回滚");
    }

    public void addBankAccount3() {
        MultiThreadingTransactionManager multiThreadingTransactionManager = new MultiThreadingTransactionManager(platformTransactionManager, 3, TimeUnit.SECONDS);
        List<Runnable> tasks = new ArrayList<>();
        tasks.add(() -> {
            BankAccount bankAccount = new BankAccount();
            bankAccount.setAccount("11111111");
            bankAccount.setBalance(10000L);
            bankAccountService.addBankAccount(bankAccount);
        });
        tasks.add(() -> {
            BankAccount bankAccount = new BankAccount();
            bankAccount.setAccount("22222222");
            bankAccount.setBalance(10000L);
            bankAccountService.addBankAccount(bankAccount);
            throw new RuntimeException("测试事务回滚");
        });
        multiThreadingTransactionManager.execute(tasks, threadPoolTaskExecutor);
    }
}
